package com.harvest.scientific.ladder.net

import BaseResponse
import com.harvest.scientific.ladder.ext.launchOnIO
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun <T> request(
    requestBlock: suspend () -> BaseResponse<T>,
    callBack: HttpCallBack<T>.() -> Unit,
): Job {
    return launchOnIO {
        request(requestBlock).collect { response ->
            withContext(Dispatchers.Main) {
                response.parseData(callBack)
            }
        }
    }
}

fun <T> request(
    lifecycleScope: CoroutineScope,
    requestBlock: suspend () -> BaseResponse<T>,
    callBack: HttpCallBack<T>.() -> Unit,
): Job {
    return lifecycleScope.launch(Dispatchers.IO) {
        request(requestBlock).collect { response ->
            withContext(Dispatchers.Main) {
                response.parseData(callBack)
            }
        }
    }
}

fun <T> request(
    lifecycleScope: CoroutineScope,
    requestBlock: suspend () -> BaseResponse<T>,
    callBack: HttpCallBack<T>.() -> Unit,
    startBlock: (() -> Unit)? = null,
    completeBlock: (() -> Unit)? = null,
): Job {
    return lifecycleScope.launch(Dispatchers.Main) {
        request(requestBlock,startBlock,completeBlock).collect { response ->
            response.parseData(callBack)
        }
    }
}

fun <T> request(
    requestBlock: suspend () -> BaseResponse<T>,
    startBlock: (() -> Unit)? = null,
    completeBlock: (() -> Unit)? = null,
): Flow<BaseResponse<T>> {
    return flow {
        emit(requestBlock())
    }.flowOn(Dispatchers.IO).onStart {
        startBlock?.invoke()
    }.onCompletion {
        completeBlock?.invoke()
    }

}

fun cancelRequest(job: Job?) {
    job?.cancel()
}

fun cancelAllRequest(jobList: MutableList<Job>?) {
    jobList?.let {
        for (job in jobList) {
            job.cancel()
        }
    }
}